#ifndef NANE_OALSOUNDSYSTEM_H
#   define  NANE_OALSOUNDSYSTEM_H

#   include "nane/SoundSystem/ISoundSystem.h"
#   include "nane/SoundSystem/OAL/OpenALAPI.h"

#   include <vector>

namespace nane
{
    class OALSoundSystem
        : public ISoundSystem
    {
    public:
        OALSoundSystem();
        ~OALSoundSystem();

    public:
        bool Initialize();
        void Shutdown();
        bool InitializeContext( float _speedOfSound );
        void ShutdownContext();
        ISoundBuffer* CreateSoundBuffer( ESoundFormat::raw_type _format, uint32 _frequency, uint16 _channels
                                                , uint16 _bitsPerSample, uint32 _size );
        byte* LockSoundBuffer( ISoundBuffer* _buffer );
        void UnlockSoundBuffer( ISoundBuffer* _buffer );
        void ReleaseSoundBuffer( ISoundBuffer* _buffer );
        
        void SetListenerPosition( float _x, float _y, float _z );
        void SetListenerOrientation( float _atX, float _atY, float _atZ, float _upX, float _upY, float _upZ );
        void SetListenerVelocity( float _x, float _y, float _z );

        ISoundSource* CreateSoundSource();
        ISoundSource3D* CreateSoundSource3D();
        void SetSource3DPosition( ISoundSource3D* _source, float _x, float _y, float _z );
        void SetSource3DVelocity( ISoundSource3D* _source, float _x, float _y, float _z );
        bool QueueSourceBuffer( ISoundSource* _source, ISoundBuffer* _buffer );
        uint32 GetSourceBuffersQueued( ISoundSource* _source );
        void ClearSourceBufferQueue( ISoundSource* _source );
        void Play( ISoundSource* _source, uint32 _posMs );
        void Stop( ISoundSource* _source );
        void ReleaseSoundSource( ISoundSource* _source );
        
    private:
        ALuint GetFreeSource_();
        void SetFreeSource_( ALuint _source );

    private:
        ALCdevice* m_device;
        ALCcontext* m_context;
        std::vector<ALuint> m_freeSources;
    };
}   // namespace nane

#endif	// NANE_OALSOUNDSYSTEM_H
